package com.jiantong.web.core.cloud.service.impl;

import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import com.google.common.base.Throwables;
import com.jiantong.web.core.cloud.service.FileServer;
import com.jiantong.web.core.util.FUtil;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;

/**
 * aliyun file server
 *
 * @author panxin
 */
@Slf4j
public class AliyunFileServer implements FileServer {

    private final String bucketName;

    private final OSSClient ossClient;

    private final ClientConfiguration clientConfiguration;

    public AliyunFileServer(String endpoint, String appKey, String appSecret, String bucketName) {
        this.bucketName = bucketName;

        this.clientConfiguration = new ClientConfiguration();
        this.clientConfiguration.setMaxConnections(10240);
        this.ossClient = new OSSClient(endpoint, appKey, appSecret,this.clientConfiguration);
        System.out.println(this.ossClient.getClientConfiguration());
    }

    @Override
    public String write(String path, MultipartFile file) throws Exception {
        try {
            try (InputStream stream = file.getInputStream()) {
                ossClient.putObject(bucketName, FUtil.upPath(path), stream);
            }
            return path;
        } catch (Exception e) {
            log.error("failed to upload file(path={}) to oss, cause:{}", path, Throwables.getStackTraceAsString(e));
            throw new Exception(e);
        }
    }

    @Override
    public String write(String path, File file) throws Exception {
        try {
            try (InputStream stream = Files.newInputStream(file.toPath())) {
                ossClient.putObject(bucketName, FUtil.upPath(path), stream);
            }
            return path;
        } catch (Exception e) {
            log.error("failed to upload file(path={}) to oss, cause:{}", path, Throwables.getStackTraceAsString(e));
            throw new Exception(e);
        }
    }

    @Override
    public String write(String path, InputStream inputStream) throws Exception {
        try {
            ossClient.putObject(bucketName, FUtil.upPath(path), inputStream);
            return path;
        } catch (Exception e) {
            log.error("failed to upload file(path={}) to oss, cause:{}", path, Throwables.getStackTraceAsString(e));
            throw new Exception(e);
        } finally {
            if(inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error("Close file inputStream failed, path={}, error code={}",
                            path, Throwables.getStackTraceAsString(e));
                }
            }
        }
    }

    @Override
    public boolean delete(String path) throws Exception {
        try {
            ossClient.deleteObject(bucketName, FUtil.upPath(path));
            return true;
        } catch (Exception e) {
            log.error("failed to delete {} from oss, cause:{}", path, Throwables.getStackTraceAsString(e));
            throw new Exception(e);
        }
    }
}
